import numpy as np
import pandas as pd

# 1、通过列表创建Series——带有标签的一列数据
s1 = pd.Series(data=[1, 2, 3, 4],
               index=['row1', 'row2', 'row3', 'row4'],
               dtype="i1")
print(s1)

# 2、通过字典创建Series
# 键作为行标签index
s2 = pd.Series({'x':1, 'y':2, 'z':3})
print(s2)

# 3、通过NumPy数组创建
s3 = pd.Series(np.arange(1, 10, 2))
print(s3)


import pandas as pd

# 通过列表创建包含多个学生信息的表格【学号 姓名 分数】
stu_data = [
    ['1001', '张三', 98],
    ['1005', '杨辉', 90],
    ['1002', '李四', 100]
]
df = pd.DataFrame(stu_data,
                  index=['row1', 'row2', 'row3'],
                  columns=['学号', '姓名', '分数'])
print(df)

# 2、通过字典创建DataFrame
df2 = pd.DataFrame(data={'学号':['1001', '1002', '1003'],
                         '姓名':["张三", "李四", "王五"],
                         '分数':[90, 89, 95]})
print(df2)

print("=============================")
import numpy as np
import pandas as pd
# nan 非数值
s = pd.Series([5, 6, np.nan, 9],
              index=['a', 'b', 'c', 'd'],
              name="张三")

# 基本属性需要掌握的
print(s.index)      # 输出索引
print(s.values)     # 输出值
print(s.dtype)      # 输出数据类型
print(s.shape)      # 输出形状
print(s.size)       # 输出大小/元素个数
print(s.nbytes)     # 输出总字节数
print(s.array)      # 输出对应的NumPy数组
print(s.name)       # 输出名称
print(s.empty)      # 输出是否为空
print(s.hasnans)    # 输出是否有nan值


print("===================================")
import numpy as np
import pandas as pd
# nan 非数值
s = pd.Series([5, 6, np.nan, 9, 10, 20, 30, 40],
              index=['a', 'b', 'c', 'd', 'x', 'y', 'z', 'w'],
              name="张三")

# 访问方式对比
# 1、位置访问——就是数据data的下标
print('--'*30)
# print(s[0])      不采用这种访问方式，会有警告
print(s[0:2])
print(s.iloc[0])
print(s.iat[0])

# 2、标签访问——就是index的值作为键进行访问
print('--'*30)
print(s['a'])
print(s['a':'c'])
print(s.loc['a'])
print(s.at['d'])

# 3、按行访问
print('--'*30)
print(s.head(-2))       # 这里的参数n还是下标，而且有正向下标和反向下标，依旧前闭后开
print(s.tail(2))
print("================================")

# 4、查询特定元素
# isin查看特定序列是否在表中，返回值是一个真值表
print(s.isin([20, 40]))
# get查看特定key是否在表中——在就返回对应值，不在就提示default
print(s.get('a', '不在表中'))
print(s.get('aaaa', '不在表中'))
print("=======================")

import numpy as np
import pandas as pd

s = pd.Series([5, 6, 7, np.nan, 8, 5, 6, 7])

# 1、对于缺失值的处理
# 缺失值：表现在表格中也就该单元格中没有值，为空
clear_s = s.dropna()
print("删除缺失值\n", clear_s)
fill_s = s.fillna(0)
print("填充缺失值\n", fill_s)
forward_fill_s = s.ffill()
print("前向填充缺失值\n", forward_fill_s)
backward_fill_s = s.bfill()
print("反向填充缺失值\n", backward_fill_s)

# 2、对于重复值的处理
drop_s = s.drop_duplicates()
print("删除重复值\n", drop_s)


print("==============================")
import numpy as np
import pandas as pd

s = pd.Series([5, 4, 7, np.nan, 8, 5, 6, 7])

# 1、使用apply(),第一个参数是函数——Python函数或者NumPy函数
apply_s = s.apply(lambda x: x**2)   # 使用Python匿名函数
print(apply_s)
apply_s = s.apply(np.sqrt)          # 使用NumPy开根号函数
print(apply_s)

# 2、使用map(),参数可以是字典映射{原值:新值}或者函数
map_s = s.map(lambda x: x**2)
print(map_s)
print("==============================")
map_s = s.map({5:66, 7:99})
print(map_s)

# 3、使用replace()
replace_s = s.replace({5:66, 7:99})
print(replace_s)

"""
总结来说：
1. 若只是想要修改某些值，就使用replace
2. 若想修改整个表格的数据，使用apply/map传参函数
"""

